package com.ruoyi.utils;


import com.ruoyi.common.utils.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * http客户端
 */
public class HttpClient {

    /*
     * post请求传输map数据
     */
    public static String sendPostDataByMap(String url, Map<String, String> map, String encoding) throws ClientProtocolException, IOException {
        String result = "";
        // 创建httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 创建post方式请求对象
        HttpPost httpPost = new HttpPost(url);
        // 装填参数
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        if (map != null) {
            for (Entry<String, String> entry : map.entrySet()) {
                nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
        }
        // 设置参数到请求对象中
        httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, encoding));
        // 设置header信息
        // 指定报文头【Content-type】、【User-Agent】
        httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
        httpPost.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

        // 执行请求操作，并拿到结果（同步阻塞）
        CloseableHttpResponse response = httpClient.execute(httpPost);
        // 获取结果实体
        // 判断网络连接状态码是否正常(0--200都数正常)
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            result = EntityUtils.toString(response.getEntity(), "utf-8");
        }
        // 释放链接
        response.close();

        return result;
    }

    /**
     * 请求氚云接口：post请求传输json数据
     */
    public static String sendPostDataByJson(String url, String json) throws ClientProtocolException, IOException {
        String result = "";

        // 创建httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建post方式请求对象
        HttpPost httpPost = new HttpPost(url);

        // 设置参数到请求对象中
        StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);
        stringEntity.setContentEncoding("utf-8");
        httpPost.setEntity(stringEntity);
        // 指定报文头【Content-type】、【User-Agent】
        httpPost.setHeader("EngineCode", "e4filulbe0ix59491kgfnarf0");
        httpPost.setHeader("EngineSecret", "as0CNp0VR70RMZz+6eWPAuLdFRMzR6ow5afh6XTgHUd/oSOpT2isrQ==");
        httpPost.setHeader("Content-Type", "application/json");

        // 执行请求操作，并拿到结果（同步阻塞）
        CloseableHttpResponse response = httpClient.execute(httpPost);

        // 获取结果实体
        // 判断网络连接状态码是否正常(0--200都数正常)
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            result = EntityUtils.toString(response.getEntity(), "utf-8");
        }
        // 释放链接
        response.close();
        return result;
    }

    /*
     * get请求传输数据
     */
    public static String sendGetData(String url, String encoding) throws ClientProtocolException, IOException {
        String result = "";
        // 创建httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 创建get方式请求对象
        HttpGet httpGet = new HttpGet(url);
        httpGet.addHeader("Content-type", "application/json");
        // 通过请求对象获取响应对象
        CloseableHttpResponse response = httpClient.execute(httpGet);
        // 获取结果实体
        // 判断网络连接状态码是否正常(0--200都数正常)
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            result = EntityUtils.toString(response.getEntity(), "utf-8");
        }
        // 释放链接
        response.close();
        return result;
    }

    public static String doGet(String url, Map<String, String> param,Map<String, String> headers) {
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();
            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);
            if (headers != null) {
                for (String key : headers.keySet()) {
                    httpGet.setHeader(key, headers.get(key));
                }
            }
            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }


    /**
     * @param url        请求的url地址
     * @param headers    请求头参数map
     * @param parameters 请求参数map
     * @return 请求的结果字符串
     * 发起PUT同步请求
     */
    public static String doPut(String url, Map<String, String> headers, Map<String, String> parameters, String jsonStr) throws UnsupportedEncodingException {
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        HttpPut httpPut = new HttpPut(url);
        addParameters(httpPut, parameters, jsonStr);
        return getResultStr(headers, httpClient, httpPut);
    }

    private static void addParameters(HttpEntityEnclosingRequestBase postPutRequest, Map<String, String> parameters, String jsonStr) throws UnsupportedEncodingException, UnsupportedEncodingException {
        if (!StringUtils.isEmpty(jsonStr)) {
            postPutRequest.setHeader("Content-Type", "application/json;charset=UTF-8");
            postPutRequest.setEntity(new StringEntity(jsonStr, Charset.forName("UTF-8")));
        } else {

            // 1、构造list集合，往里面存请求的数据
            List<NameValuePair> list = new ArrayList<>();
            for (String key : parameters.keySet()) {
                String value = parameters.get(key);
                BasicNameValuePair basicNameValuePair = new BasicNameValuePair(key, value);
                list.add(basicNameValuePair);
            }
            //2 我们发现Entity是一个接口，所以只能找实现类，发现实现类又需要一个集合，集合的泛型是NameValuePair类型
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list, Consts.UTF_8);
            //3 通过setEntity 将我们的entity对象传递过去
            postPutRequest.setEntity(formEntity);
        }

    }

    private static String getResultStr(Map<String, String> headers, CloseableHttpClient httpClient, HttpRequestBase httpRequest) {
        String body = null;
        CloseableHttpResponse response;
        //设置请求头的参数
        setHeaders(headers, httpRequest);
        try {
            //执行请求
            response = httpClient.execute(httpRequest);
            //请求成功执行
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                //获取返回的数据
                HttpEntity entity = response.getEntity();
                //转换成字符串
                body = EntityUtils.toString(entity);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return body;
    }

    private static void setHeaders(Map<String, String> headers, HttpRequestBase httpRequest) {
        if (headers != null && !headers.isEmpty()) {
            for (String key : headers.keySet()) {
                String value = headers.get(key);
                httpRequest.setHeader(key, value);
            }
        }
    }



//    @Test
//    public void testSendPostDataByMap() throws ClientProtocolException, IOException {
//        String url = "http://localhost:8089/httpService/sendPostDataByMap";
//        Map<String, String> map = new HashMap<String, String>();
//        map.put("name", "wyj");
//        map.put("city", "南京");
//        String body = sendPostDataByMap(url, map, "utf-8");
//        System.out.println("响应结果：" + body);
//    }
//
//
//    @Test
//    public void testSendGetData() throws ClientProtocolException, IOException {
//        String url = "http://localhost:8089/httpService/sendGetData?name=wyj&city=南京";
//        String body = sendGetData(url, "utf-8");
//        System.out.println("响应结果：" + body);
//    }

}